package com.bytz.modules.cms.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bytz.common.util.mentity.EntityMergeInfoV2;
import com.bytz.common.util.mentity.util.MergeEntityUtil;
import com.bytz.modules.cms.order.entity.OrderItem;
import com.bytz.modules.cms.order.entity.OrderPickUpDetail;
import com.bytz.modules.cms.order.mapper.OrderItemMapper;
import com.bytz.modules.cms.order.service.IOrderItemService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 莱宝CMS—订单管理-订单商品表 服务实现类
 * </p>
 *
 * @author KyleWang
 * @since 2022-10-10
 */
@Service
public class OrderItemServiceImpl extends ServiceImpl<OrderItemMapper, OrderItem> implements IOrderItemService {

    @Override
    public boolean removeByOrderId(String orderId) {
        return lambdaUpdate().eq(OrderItem::getOrderId, orderId).remove();
    }

    @Override
    public List<OrderItem> getByOrderId(String orderId) {

        if (StringUtils.isBlank(orderId)) {
            return new ArrayList<>();
        }

        return lambdaQuery().eq(OrderItem::getOrderId, orderId).list();
    }

    @Override
    public List<OrderItem> getByOrderIdAndProductNumber(String orderId, String productNumber) {

        return lambdaQuery()
                .eq(OrderItem::getOrderId, orderId)
                .eq(OrderItem::getProductNumber, productNumber)
                .list();
    }

    @Override
    public List<OrderItem> mergeItem(String orderId, List<OrderItem> newData) {

        newData.forEach(item -> item.setOrderId(orderId));

        EntityMergeInfoV2<OrderItem> mergeInfo = MergeEntityUtil.calculateEntityMergeInfo(
                newData,
                getByOrderId(orderId));
        return MergeEntityUtil.doDbMerge(mergeInfo, this);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePrepayPrice(List<OrderItem> orderItems) {
        for (OrderItem orderItem : orderItems) {
            lambdaUpdate()
                    .set(OrderItem::getPrepayPrice, orderItem.getPrepayPrice())
                    .eq(OrderItem::getId, orderItem.getId())
                    .update();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void directSubmitPrepay(List<OrderItem> orderItems) {
        for (OrderItem orderItem : orderItems) {
            lambdaUpdate()
                    // 如果没有线上付，直接更新为首付
                    .set(OrderItem::getPaidPrice, orderItem.getPrepayPrice())
                    .set(OrderItem::getPrepayPrice, orderItem.getPrepayPrice())
                    .eq(OrderItem::getId, orderItem.getId())
                    .update();
        }
    }

    @Override
    public void submitBalancePay(List<OrderItem> orderItems, List<OrderPickUpDetail> pickUpDetails) {
        Map<String, OrderPickUpDetail> pickUpMap = pickUpDetails.stream()
                .collect(Collectors.toMap(OrderPickUpDetail::getOrderItemId, v -> v));

        for (OrderItem orderItem : orderItems) {
            OrderPickUpDetail pickUpDetail = pickUpMap.get(orderItem.getId());

            if (pickUpDetail != null) {
                // 更新已发货数量
                orderItem.setShippedNum(orderItem.getShippedNum() + pickUpDetail.getShippedNum());
                orderItem.setPaidPrice(orderItem.getPaidPrice().add(pickUpDetail.getPaidPrice()));

                lambdaUpdate()
                        // 如果没有线上付，直接操作
                        .set(OrderItem::getPaidPrice, orderItem.getPaidPrice())
                        .set(OrderItem::getShippedNum, orderItem.getShippedNum())
                        .eq(OrderItem::getId, orderItem.getId())
                        .update();
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitPrepay(String orderId) {
        lambdaUpdate()
                .setSql("paid_price = prepay_price")
                .eq(OrderItem::getOrderId, orderId)
                .update();
    }
}
